import time
import threading
from tool.string_tool import remove_punctuation


class BaseStrategy:
    def __init__(self, config):
        self.config = config

    def do_search(self, global_resource, request_content, response_content):
        """
        调用自身方法,按照base strategy 方法完成本次query
        最终返回结果
        :return:
        """
        # valid check
        if not self.is_valid(global_resource, request_content, response_content):
            print("query is not valid")
            raise Exception("query not valid")

        # query analyse
        t = threading.Thread(target=self.do_query_analyse, args=(global_resource, request_content, response_content))
        t.start()
        t.join(self.config["timer"]["query_analyse"])
        if t.is_alive():
            raise TimeoutError("query analyse time out ")

        # retrieve
        t = threading.Thread(target=self.do_retrieve, args=(global_resource, request_content, response_content))
        t.start()
        t.join(self.config["timer"]["retrieve"])
        if t.is_alive():
            raise TimeoutError("retrieve time out ")

        # merge
        t = threading.Thread(target=self.do_merge, args=(global_resource, request_content, response_content))
        t.start()
        t.join(self.config["timer"]["merge"])
        if t.is_alive():
            raise TimeoutError("merge time out ")

        # rank
        t = threading.Thread(target=self.do_rank, args=(global_resource, request_content, response_content))
        t.start()
        t.join(self.config["timer"]["rank"])
        if t.is_alive():
            raise TimeoutError("rank time out ")

        # adjust
        t = threading.Thread(target=self.do_adjust, args=(global_resource, request_content, response_content))
        t.start()
        t.join(self.config["timer"]["adjust"])
        if t.is_alive():
            raise TimeoutError("adjust time out ")

        response_content.store_value("search_success", True)

    def do_query_analyse(self, global_resource, request_content, response_content):
        service_list = []
        for qa_name in self.config["query_analyse"]:
            qa_service = global_resource.query_analyse_manager.get_service(qa_name)
            qa_service.init(global_resource, request_content, response_content)
            qa_service.setDaemon(True)
            qa_service.start()
            service_list.append(qa_service)

        for i, service in enumerate(service_list):
            # 启动多线程调用所有的service
            service.join()

    def do_retrieve(self, global_resource, request_content, response_content):
        service_list = []
        for retrieve_name in self.config["retrieve"]:
            retrieve_service = global_resource.retrieve_manager.get_service(retrieve_name)
            retrieve_service.init(global_resource, request_content, response_content)
            retrieve_service.setDaemon(True)
            retrieve_service.start()
            service_list.append(retrieve_service)

        for i, service in enumerate(service_list):
            # 启动多线程调用所有的service
            service.join()

    def do_merge(self, global_resource, request_content, response_content):
        service_list = []
        for merge_name in self.config["merge"]:
            merge_service = global_resource.merge_manager.get_service(merge_name)
            merge_service.init(global_resource, request_content, response_content)
            merge_service.setDaemon(True)
            merge_service.start()
            service_list.append(merge_service)

        for i, service in enumerate(service_list):
            # 启动多线程调用所有的service
            service.join()

    def do_rank(self, global_resource, request_content, response_content):
        service_list = []
        for rank_name in self.config["rank"]:
            rank_service = global_resource.rank_manager.get_service(rank_name)
            rank_service.init(global_resource, request_content, response_content)
            rank_service.setDaemon(True)
            rank_service.start()
            service_list.append(rank_service)

        for i, service in enumerate(service_list):
            # 启动多线程调用所有的service
            service.join()

    def do_adjust(self, global_resource, request_content, response_content):
        service_list = []
        for adjust_name in self.config["adjust"]:
            adjust_service = global_resource.adjust_manager.get_service(adjust_name)
            adjust_service.init(global_resource, request_content, response_content)
            adjust_service.setDaemon(True)
            adjust_service.start()
            service_list.append(adjust_service)

        for i, service in enumerate(service_list):
            # 启动多线程调用所有的service
            service.join()

    def is_valid(self, global_resource, request_content, response_content):
        """
        判断 query 是否合法
        :return:
        """
        raw_query = request_content.get_value("raw_query")
        clean_query = remove_punctuation(raw_query)
        if not clean_query:
            return False
        return True

